using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using My.IdlConverter.Core;
using My.IdlConverter.Core.Util;
using My.IdlConverter.Core.Producers;
using My.IdlConverter.Core.Types;

namespace My.IdlConverter.Com
{
    public class ComMethodProducer : MethodProducer
    {
        private int _id;

        public ComMethodProducer()
        {
        }
        public ComMethodProducer(Method consumer,int id)
            : base(consumer)
        {
            _id = id;
        }

        public int ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }

        public override string Produce()
        {
            Debug.Assert(_id >= 0);
            string prefix;
            string methodName = Consumer.Name;
            if (Consumer.Getter)
            {
                prefix = "propget,";
                methodName = methodName.Remove(0,"Get".Length);
                StringUtil.CapitalString(ref methodName);
            }
            else if (Consumer.Setter)
            {
                prefix = "propput,";
                methodName = methodName.Remove(0, "Set".Length);
                StringUtil.CapitalString(ref methodName);
            }
            else
                prefix = "";
            string helpString = "helpstring(\"" + Consumer.Name + "\")";

            StringBuilder sb = new StringBuilder();
            sb.Append("[");
            sb.Append(prefix);
            sb.AppendFormat("id({0}),",_id);
            sb.Append(helpString);
            sb.Append("]");
            sb.Append("HRESULT " + methodName);
            IList<Parameter> parameters = Consumer.Parameters;
            int paramCount = parameters.Count;
            if ( paramCount == 0)
                sb.Append("(");
            else
            {
                sb.Append("(");
                IProducer<Parameter> paramProducer = new ComParameterProducer();
                foreach (Parameter nextParam in parameters)
                {
                    paramProducer.Consumer = nextParam;
                    sb.Append(paramProducer.Produce() + ",");
                }
            }
            IType IdlConverterReturnType = Consumer.ReturnType;
            IType returnType = IdlConverterReturnType.Substitution.SubstitutionTypes[0].Type;
            EmptyType voidType = returnType as EmptyType;
            if (voidType == null)
            {
                ITypeFormatter typeFormatter = new TypeFormatter(IdlConverterReturnType, 
                    TypeFormatStrategyFactory.Create(TypeFormatStrategyFactory.ReturnType));
                sb.AppendFormat("[out,retval]{0}* {1}", typeFormatter.Format(), GlobalConst.MethodReturnVarName);
            }
            else
            {
                int endCharIndex = sb.Length - 1; 
                if (sb[endCharIndex] == ',')
                    sb.Remove(endCharIndex, 1);
            }
            sb.Append(")");
            sb.Append(";");

            return sb.ToString();
        }
    }
}
